package Threading2;

public class ThreadingDemo6 {
    public static void main2(String[] args) {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "：我还活着！！"); // 获得当前线程的名字
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + "：我即将死去！！");
        });

        System.out.println(Thread.currentThread().getName() + "：ID：" + t.getId());
        System.out.println(Thread.currentThread().getName() + "：名称：" + t.getName());
        System.out.println(Thread.currentThread().getName() + "：状态：" + t.getState());
        System.out.println(Thread.currentThread().getName() + "：优先级：" + t.getPriority());
        System.out.println(Thread.currentThread().getName() + "：后台线程" + t.isDaemon());
        System.out.println(Thread.currentThread().getName() + "：活着" + t.isAlive());
        System.out.println(Thread.currentThread().getName() + "：被中断" + t.isInterrupted());
        System.out.println(Thread.currentThread().getName() + "：状态" + t.getState());

        t.start();
        while (t.isAlive()) {
            System.out.println(Thread.currentThread().getName() + "：状态" + t.getState());
        }
    }

    public static void main1(String[] args) {
        Thread t = new Thread(() -> {
            while (true) {
                System.out.println("hello tt");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "我的线程");

        t.start();
    }

    public static boolean isQuite = false;  // lambda 表达式捕获成员变量的时候不受之前的变量捕获规则
    public static void main3(String[] args) {
        // boolean isQuite = false; // 这个变量不能放在main方法里面，下面使用这个变量的是 lambda 表达式，
        // lambda 中的表达式必须是 final 修饰的常量 / 实际常量（就是没有被改变过的变量）
        // 如果此时换成成员变量此时lambda表达式就不受之前的变量捕获的规则了
        // 线程的中断
        // 创建的线程默认是前台线程
        Thread t = new Thread(() -> {
            while (!isQuite) {  // 通过一个循环变量来控制线程的开始和结束
                System.out.println("hello t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t.start();
        // 在主线程中, 修改 isQuite 这个变量
        try {
            Thread.sleep(5000);
            isQuite = true;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    // 这个逻辑就是先执行 t 线程，先让主线程进行休眠，之后再执行主线程，主线程执行完成后，整个进程就结束了

    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            // 这个 currentThread 是获取到当前线程实例（在哪一个线程中调用这个currentThread 这个 currentThread 就代表哪一个线程）
            // 此处 currentThread 得到的对象就是 t  （所以此处写成t也是可以的）
           while (!Thread.currentThread().isInterrupted()) {
               // isInterrupted 就是 t 对象里自带的一个标志位 默认就是false
               System.out.println("hello y");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
                   break; // 这个就是 sleep 清空标志位之后 会继续循环，如果强制唤醒
                   // 此时就会以 catch 的方式来打印出当前调用栈，此时后面加一个 break 就
                   // 可以结束当前循环
               }
           }
        });
        t.start();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 下面代码就是将标志位设置成 true
        t.interrupt();
    }

    // 总结：interrupt 方法的作用：
    // 1. 设置标志位为 true    2. 如果当前线程正在阻塞中（比如正在执行 sleep）
    // 此时就会把阻塞状态唤醒 （通过抛出异常的方式 让 sleep 立即结束）
    // 还有一个细节就是：当 sleep被强制唤醒的时候，sleep就会自动的把 isInterrupted 的
    // 标志位清空（也就是还原成默认的false），此时就导致上述代码不会结束，还会继续执行

    // 如果需要结束循环 需要在当前的 catch 中搞一个 break 显示的结束当前循环



}
